// Package types defines core data structures and interfaces for the smart snapshotter
package types

import (
	"context"
	"time"
)

// Snapshot represents a container snapshot
type Snapshot struct {
	ID          string
	ParentID    string
	Labels      map[string]string
	CreatedAt   time.Time
	UpdatedAt   time.Time
	Size        int64
	Metadata    map[string]interface{}
}

// Layer represents a container image layer
type Layer struct {
	ID          string
	Digest      string
	Size        int64
	CreatedAt   time.Time
	Metadata    map[string]interface{}
}

// StorageBackend defines the interface for storage operations
type StorageBackend interface {
	// File operations
	StoreFile(ctx context.Context, hash string, data []byte) error
	LoadFile(ctx context.Context, hash string) ([]byte, error)
	DeleteFile(ctx context.Context, hash string) error
	FileExists(ctx context.Context, hash string) (bool, error)

	// Block operations
	StoreBlock(ctx context.Context, hash string, data []byte) error
	LoadBlock(ctx context.Context, hash string) ([]byte, error)
	DeleteBlock(ctx context.Context, hash string) error
	BlockExists(ctx context.Context, hash string) (bool, error)

	// Metadata operations
	StoreMetadata(ctx context.Context, key string, metadata []byte) error
	LoadMetadata(ctx context.Context, key string) ([]byte, error)
	DeleteMetadata(ctx context.Context, key string) error

	// Health check
	Health(ctx context.Context) error
}

// DedupEngine defines the interface for deduplication operations
type DedupEngine interface {
	// File-level deduplication
	AddFile(ctx context.Context, path string, data []byte) (string, error)
	GetFile(ctx context.Context, hash string) ([]byte, error)
	DeleteFile(ctx context.Context, hash string) error
	FileExists(ctx context.Context, hash string) (bool, error)

	// Block-level deduplication
	AddBlock(ctx context.Context, data []byte) (string, error)
	GetBlock(ctx context.Context, hash string) ([]byte, error)
	DeleteBlock(ctx context.Context, hash string) error
	BlockExists(ctx context.Context, hash string) (bool, error)

	// Block processing
	ProcessBlocks(ctx context.Context, data []byte) ([]BlockInfo, error)
	ReconstructFile(ctx context.Context, blocks []BlockInfo) ([]byte, error)

	// Snapshot processing
	ProcessSnapshot(ctx context.Context, snapshotID string, path string) error
	RemoveSnapshot(ctx context.Context, snapshotID string) error
	GetSnapshotUsage(ctx context.Context, snapshotID string) (Usage, error)

	// Statistics
	GetStats(ctx context.Context) (DedupStats, error)
	ResetStats(ctx context.Context) error
	Close() error
}

// DedupStats contains deduplication statistics
type DedupStats struct {
	TotalFiles      int64
	UniqueFiles     int64
	TotalBlocks     int64
	UniqueBlocks    int64
	SpaceSaved      int64
	DedupRatio      float64
	LastUpdated     time.Time
}

// BlockInfo represents block information for deduplication
type BlockInfo struct {
	Hash      string
	Size      int64
	Offset    int64
	Reference int64
}

// Usage represents usage information
type Usage struct {
	Size   int64
	Inodes int64
}

// Cache defines the interface for caching operations
type Cache interface {
	Get(ctx context.Context, key string) ([]byte, error)
	Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
	Delete(ctx context.Context, key string) error
	Exists(ctx context.Context, key string) (bool, error)
	Clear(ctx context.Context) error
	GetStats(ctx context.Context) (CacheStats, error)
}

// CacheStats contains cache statistics
type CacheStats struct {
	Hits        int64
	Misses      int64
	Evictions   int64
	Size        int64
	Capacity    int64
	HitRatio    float64
}

// Loader defines the interface for on-demand loading
type Loader interface {
	Load(ctx context.Context, key string) ([]byte, error)
	Prefetch(ctx context.Context, keys []string) error
	GetProgress(ctx context.Context, key string) (LoadingProgress, error)
	GetStats(ctx context.Context) (LoaderStats, error)
}

// LoadingProgress contains loading progress information
type LoadingProgress struct {
	Key           string
	Status        string // "pending", "loading", "completed", "failed"
	BytesLoaded   int64
	BytesTotal    int64
	StartTime     time.Time
	EndTime       time.Time
	Error         error
}

// LoaderStats contains loader statistics
type LoaderStats struct {
	TotalRequests    int64
	CacheHits        int64
	CacheMisses      int64
	PrefetchRequests int64
	ActiveDownloads  int64
	TotalBytesLoaded int64
	AverageLoadTime  time.Duration
}

// Config contains system configuration
type Config struct {
	Storage     StorageConfig
	Dedup       DedupConfig
	Cache       CacheConfig
	Loader      LoaderConfig
	Metrics     MetricsConfig
	Logging     LoggingConfig
}

// StorageConfig contains storage configuration
type StorageConfig struct {
	Type        string `yaml:"type"`        // "erofs", "composefs", "overlay"
	BasePath    string `yaml:"base_path"`
	MaxSize     int64  `yaml:"max_size"`
	Compression bool   `yaml:"compression"`
	Encryption  bool   `yaml:"encryption"`
}

// DedupConfig contains deduplication configuration
type DedupConfig struct {
	Enabled         bool   `yaml:"enabled"`
	Algorithm       string `yaml:"algorithm"`        // "file", "block", "both"
	BlockSize       int    `yaml:"block_size"`       // for block-level dedup
	MinFileSize     int64  `yaml:"min_file_size"`    // minimum file size for dedup
	HashAlgorithm   string `yaml:"hash_algorithm"`   // "sha256", "blake3"
}

// CacheConfig contains cache configuration
type CacheConfig struct {
	Type        string        `yaml:"type"`        // "memory", "disk", "hybrid"
	MaxSize     int64         `yaml:"max_size"`
	TTL         time.Duration `yaml:"ttl"`
	Strategy    string        `yaml:"strategy"`    // "lru", "lfu"
}

// LoaderConfig contains loader configuration
type LoaderConfig struct {
	PrefetchEnabled bool          `yaml:"prefetch_enabled"`
	PrefetchDepth   int           `yaml:"prefetch_depth"`
	MaxConcurrency  int           `yaml:"max_concurrency"`
	Timeout         time.Duration `yaml:"timeout"`
}

// MetricsConfig contains metrics configuration
type MetricsConfig struct {
	Enabled bool   `yaml:"enabled"`
	Port    int    `yaml:"port"`
	Path    string `yaml:"path"`
}

// LoggingConfig contains logging configuration
type LoggingConfig struct {
	Level      string `yaml:"level"`
	Format     string `yaml:"format"`
	Output     string `yaml:"output"`
	FilePath   string `yaml:"file_path"`
}